package rdw.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.DataOutputStream;
import java.net.*;
import java.util.Enumeration;

import rdw.robot.RobotCallback;

/**
 * HttpServer is a simple web server that handles GET requests.
 */
public class HttpServer extends Thread
{
	private ServerSocket server;
	private int	port;
	private boolean shutdown;
	private RobotCallback callback;

	public HttpServer(int port, RobotCallback callback) throws IOException
	{
		this.callback = callback;
		this.port = port;
		this.shutdown = false;
		this.server = new ServerSocket(port, 5, null);
		
		getBoundIps();
	}
	
	public int getPort()
	{
		return this.port;
	}
	
	public void setPort(int port)
	{
		this.port = port;
		this.shutdown = true;
	}
	
	public String getBoundIps()
	{
		String ipAddresses = "";

		try
		{
			Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces();
		
			while (netInterfaces.hasMoreElements())
			{
				NetworkInterface ni= (NetworkInterface) netInterfaces.nextElement();
				
				if (ni.isLoopback())
				{
					continue;
				}
				
				Enumeration inetAddresses = ni.getInetAddresses();

				while (inetAddresses.hasMoreElements())
				{
					InetAddress ip = (InetAddress) inetAddresses.nextElement();
					if (ip instanceof Inet4Address)
					{
						ipAddresses += ip.toString() + " "; 
					}
				}
			}
		}
		catch (SocketException e)
		{
			return "Unable to determine IP addresses.";
		}
		
		return ipAddresses;
	}
	
	public void shutdown()
	{
		this.shutdown = true;
		try
		{
			this.server.close();
		}
		catch (IOException e)
		{
		}
		this.server = null;

		try
		{
			this.join();
		}
		catch (InterruptedException e)
		{
		}
	}
	
	/**
	 * run accepts connections, creates output and input streams, and passes the request 
	 * to HttpGetRequest.
	 */
	public void run()
	{
		while (!shutdown)
		{
			try
			{
				System.out.println("Waiting for connection");
				Socket socket = this.server.accept();
				DataOutputStream out = new DataOutputStream(socket.getOutputStream());
				BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

				String getUrl = in.readLine();
				HttpGetRequest clientRequest = new HttpGetRequest(out, this.callback);
				clientRequest.handleRequest(getUrl);
				
				out.close();
				out = null;
				in.close();
				in = null;
				socket.close();
				socket = null;
			}
			catch (SocketException e)
			{
			}
			catch (IOException e)
			{
				System.out.println("Error reading/parsing HTTP GET request");
				e.printStackTrace();
			}
		}
	}
}
